<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>WebSocket Video Stream Client</title>
    <style>
        html, body {
            margin: 0;
            padding: 0;
            width: 100%;
            height: 100%;
            display: flex;
            justify-content: center;
            align-items: center;
            background-color: black; /* 设置背景颜色 */
        }
        #localVideo {
            width: 100%;
            height: 100%;
            object-fit: cover; /* 确保视频填充整个屏幕 */
        }
        #shouImage {
            position: absolute; /* 绝对定位 */
            top: 30%; /* 距离顶部的距离 */
            left: 30%; /* 距离左侧的距离 */
            width: 300px; /* 图片宽度 */
            height: auto; /* 图片高度自动调整 */
            z-index: 2; /* 确保图片在视频上方 */
        }
        #cuoImage {
            position: absolute; /* 绝对定位 */
            top: 3%; /* 距离顶部的距离 */
            left: 90%; /* 距离左侧的距离 */
            width: 55px; /* 图片宽度 */
            height: auto; /* 图片高度自动调整 */
            z-index: 1; /* 确保图片在视频上方 */
        }
        #kuangImage {
            position: absolute; /* 绝对定位 */
            top: 25%; /* 距离顶部的距离 */
            left: 5%; /* 距离左侧的距离 */
            width: 90%; /* 图片宽度 */
            height: auto; /* 图片高度自动调整 */
            z-index: 1; /* 确保图片在视频上方 */
        }
        #AIImage {
            position: absolute; /* 绝对定位 */
            top: 80%; /* 距离顶部的距离 */
            left: 20%; /* 距离左侧的距离 */
            width: 15%; /* 图片宽度 */
            height: auto; /* 图片高度自动调整 */
            z-index: 1; /* 确保图片在视频上方 */
        }
        #title {
            position: absolute; /* 绝对定位 */
            top: 3%; /* 距离顶部的距离 */
            left: 50%; /* 水平居中 */
            transform: translateX(-50%); /* 使文本水平居中 */
            color: white; /* 文本颜色 */
            font-size: 55px; /* 文本大小 */
            font-weight: bold; /* 文本加粗 */
            background-color: rgba(0, 0, 0, 0); /* 透明背景 */
            z-index: 1; /* 确保文本在视频上方 */
        }
        #action {
            position: absolute; /* 绝对定位 */
            top: 53%; /* 距离顶部的距离 */
            left: 50%; /* 水平居中 */
            transform: translateX(-50%); /* 使文本水平居中 */
            color: white; /* 文本颜色 */
            font-size: 40px; /* 文本大小 */
            background-color: rgba(0, 0, 0, 0); /* 透明背景 */
            z-index: 2; /* 确保文本在视频上方 */
        }
        #translate {
            position: absolute; /* 绝对定位 */
            top: 83%; /* 距离顶部的距离 */
            left: 55%; /* 水平居中 */
            transform: translateX(-50%); /* 使文本水平居中 */
            color: white; /* 文本颜色 */
            font-size: 40px; /* 文本大小 */
            background-color: rgba(0, 0, 0, 0); /* 透明背景 */
            z-index: 2; /* 确保文本在视频上方 */
        }
        #switchCameraButton {
            position: absolute;
            top: 10px;
            right: 10px;
            padding: 10px 20px;
            font-size: 16px;
            background-color: #4CAF50;
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
        }
        #switchCameraButton:hover {
            background-color: #45a049;
        }
    </style>
</head>
<body>
<video id="localVideo" width="100%" height="100%" autoplay="autoplay" ></video>
<div id="title">实时翻译</div>
<img id="cuoImage" src="media/cuocha.png" alt="Overlay Image">
<img id="shouImage" src="media/shou.png" alt="Overlay Image">
<img id="kuangImage" src="media/kuang.png" alt="Overlay Image">
<div id="action">请做出手语动作</div>
<div>
    <img id="AIImage" src="media/jiqiren.png" alt="Overlay Image">
    <div id="translate">我将会为您实时翻译哦</div>
</div>
<button id="switchCameraButton">切换到后置摄像头</button>

<script>
    const translateDiv = document.getElementById('translate');

    const localVideo = document.getElementById('localVideo');
    let socket;
    let isSending = true;
    let sendInterval;

    // WebSocket 连接函数
    function connectWebSocket() {
        socket = new WebSocket('ws://1.95.63.100:8080/ws');

        socket.onopen = () => {
            console.log("Connection established successfully.");
            // 成功连接后获取摄像头视频流
            navigator.mediaDevices.getUserMedia({ video: { facingMode: 'environment' } })
                .then(stream => {
                    localVideo.srcObject = stream;
                    console.log("Camera stream started.");

                    const videoTrack = stream.getVideoTracks()[0];
                    const videoProcessor = new VideoProcessor(videoTrack);
                    videoProcessor.startSending(socket);
                })
                .catch(error => {
                    console.error("Error accessing camera:", error);
                    alert("Failed to access camera: " + error.message);
                });
        };

        socket.onmessage = (event) => {
            console.log("Received message from server:", event.data);
            // 处理二进制数据（可选，根据实际需求）
            if (event.data instanceof Blob) {
                event.data.arrayBuffer().then(buffer => {
                    const bytes = new Uint8Array(buffer);
                    console.log("Received binary data:", bytes);
                });
            }
            // 处理文本数据（翻译结果）
            else if (typeof event.data === 'string') {
                translateDiv.textContent = event.data;
                console.log("Received event.data data:", event.data);
            }
        };

        socket.onclose = (event) => {
            console.log("Connection closed:", event.reason);
            isSending = false;
            clearInterval(sendInterval);
            // 尝试重新连接
            setTimeout(connectWebSocket, 5000);
        };

        socket.onerror = (error) => {
            console.error("WebSocket Error:", error);
            alert("WebSocket connection error: " + error.message);
            isSending = false;
            clearInterval(sendInterval);
            // 尝试重新连接
            setTimeout(connectWebSocket, 5000);
        };
    }

    // 初始化 WebSocket 连接
    connectWebSocket();

    class VideoProcessor {
        constructor(track) {
            this.track = track;
            this.canvas = document.createElement('canvas');
            this.context = this.canvas.getContext('2d');
        }

        startSending(socket) {
            const frameInterval = 1000 / 5; // 降低帧率到 5 FPS
            sendInterval = setInterval(() => {
                if (!isSending) return;

                try {
                    // 降低分辨率
                    const settings = this.track.getSettings();
                    this.canvas.width = settings.width / 2; // 宽度减半
                    this.canvas.height = settings.height / 2; // 高度减半
                    this.context.drawImage(localVideo, 0, 0, this.canvas.width, this.canvas.height);

                    // 转换为 JPEG Blob（二进制格式）
                    this.canvas.toBlob((blob) => {
                        if (isSending && socket.readyState === WebSocket.OPEN) {
                            // 打印发送的二进制数据
                            blob.arrayBuffer().then(buffer => {
                                const bytes = new Uint8Array(buffer);
                                console.log("Sending binary data:", bytes);
                            });

                            // 发送二进制数据
                            socket.send(blob);
                            console.log("Sent frame data as binary.");
                        }
                    }, 'image/jpeg', 0.3); // 质量为 0.3
                } catch (error) {
                    console.error("Error processing video frame:", error);
                }
            }, frameInterval);
        }
    }
</script>
</body>
</html>